/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package service;

import com.openbrew.openbrewrf.FinishedGoodsInventory;
import com.openbrew.openbrewrf.LossLog;
import com.openbrew.openbrewrf.ScanTblKeg;
import java.util.List;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import service.miscListModels.KegList;
import tools.InventoryModifiers;
import tools.KegTools;
import tools.POSVolumeModifier;

/**
 *
 * @author chapmand
 */
@Stateless
@Path("com.openbrew.openbrewrf.scantblkeg")
public class ScanTblKegFacadeREST extends AbstractFacade<ScanTblKeg> {
    @PersistenceContext(unitName = "com.openBrew_openBrewRF_war_1.0PU")
    private EntityManager em;

    public ScanTblKegFacadeREST() {
        super(ScanTblKeg.class);
    }

    @POST
    @Override
    @WebMethod(operationName = "create")
    @Consumes({"application/xml", "application/json"})
    public ScanTblKeg create(@WebParam(name = "scantblkeg") ScanTblKeg entity) {
        entity = super.create(entity);
        return entity;
    }

    @PUT
    @Override
    @Consumes({"application/xml", "application/json"})
    public void edit(ScanTblKeg entity) {
        //First find if it was an unsold keg.
        boolean wasUnSold = false;
        if(super.find(entity.getKegID()).getKegCust()==null){
            wasUnSold = true;
        }
        //Update keg
        super.edit(entity);
        //If it was unsold and is now sold to a customer we need to run some items.
        if(wasUnSold && (super.find(entity.getKegID()).getKegCust()!=null)){
            POSVolumeModifier vm = new POSVolumeModifier();
            vm.doVolumeAddition(em, entity);
        }
    }

    @POST
    @Path("processScannedKegFill")
    @Consumes({"application/xml", "application/json"})
    public void editScanKegFill(List<ScanTblKeg> entities) {
        if(entities != null){
            for(ScanTblKeg entity : entities){
                super.edit(entity);
            }
            //Now adjust tank volume
            //Beer Inventory, and movment tables.
            final KegTools kt = new KegTools();
            kt.doProcessKegPackagingList(em, entities);
        }
    }

    @POST
    @Path("runKegList")
    @Consumes({"application/xml", "application/json"})
    public void runKegList(KegList entity) {
        if(entity.getScanTblKeg() != null){
            for(ScanTblKeg keg : entity.getScanTblKeg()){
                super.edit(keg);
            }
            //Now adjust tank volume
            //Beer Inventory, and movment tables.
            final KegTools kt = new KegTools();
            kt.doProcessKegPackagingList(em, entity.getScanTblKeg());
        }
    }

    @POST
    @Path("processKegSplitAndroid/{oldKegID}")
    @Consumes({"application/xml", "application/json"})
    public void doKegSplit(@PathParam("oldKegID") int oldKegID, KegList entity) {
        final InventoryModifiers im = new InventoryModifiers();
        final ScanTblKeg oldKeg = super.find(oldKegID);
        //Find old fgi value and remove from inventory.
        FinishedGoodsInventory oldFGI = oldKeg.getKegFGI();
        if(oldFGI == null){
            oldFGI = getFGIViaPkgAndBeer(oldKeg.getKegPackageID().getPackageTypeID()
                    , oldKeg.getKegBeer().getbId());
        }
        im.doFGIRemovalWithoutAllocation(em, oldFGI.getFgiid(), 1);
        
        //Add new fgis into inventory.
        float newVolume = 0;
        if(entity.getScanTblKeg() != null){
            for(ScanTblKeg keg : entity.getScanTblKeg()){
                final FinishedGoodsInventory fgi = getFGIViaPkgAndBeer(
                        keg.getKegPackageID().getPackageTypeID()
                        , oldKeg.getKegBeer().getbId());
                keg.setKegBatch(oldKeg.getKegBatch());
                keg.setKegBeer(oldKeg.getKegBeer());
                keg.setKegFGI(fgi);
                super.edit(keg);
                im.doFGIAddition(em, fgi, 1);
                newVolume += keg.getKegPackageID().getPackageTypeVol();
            }
        }
        
        //Check volumes and determine if we need to enter a loss.
        final float volumeLeft = oldKeg.getKegPackageID().getPackageTypeVol() - newVolume;
        if(volumeLeft > 0){
            final java.util.Date MoveDate = new java.util.Date();
            LossLog loss = new LossLog();
            loss.setLAngelShare(0);
            loss.setLBeerID(0);
            loss.setLBtl(0);
            loss.setLCellar(0);
            loss.setLKeg(volumeLeft);
            loss.setLDate(MoveDate);
            loss.setLNotes("Loss due to keg transfer");
            em.persist(loss);
        }
        
        //Reset old keg customer info.
        oldKeg.setKegCust(null);
        em.merge(oldKeg);
    }

    @POST
    @Path("processScannedBarrelAgedKegFill/{bcsid}")
    @Consumes({"application/xml", "application/json"})
    public void editScanBarrelAgedKegFill(@PathParam("bcsid") int bcsid, List<ScanTblKeg> entities) {
        if(entities != null){
            for(ScanTblKeg entity : entities){
                super.edit(entity);
            }
            //Now adjust tank volume
            //Beer Inventory, and movment tables.
            final KegTools kt = new KegTools();
            kt.doProcessBarrelAgedKegPackagingList(em, entities, bcsid);
        }
    }

    @POST
    @Path("processScannedBarrelAgedKegFillAndroid/{bcsid}")
    @Consumes({"application/xml", "application/json"})
    public void editScanBarrelAgedKegFillAndroid(@PathParam("bcsid") int bcsid, KegList entity) {
        if(entity.getScanTblKeg() != null){
            for(ScanTblKeg keg : entity.getScanTblKeg()){
                super.edit(keg);
            }
            //Now adjust tank volume
            //Beer Inventory, and movment tables.
            final KegTools kt = new KegTools();
            kt.doProcessBarrelAgedKegPackagingList(em, entity.getScanTblKeg(), bcsid);
        }
    }

    @POST
    @Path("processKegSplit/{oldKegID}")
    @Consumes({"application/xml", "application/json"})
    public void doKegSplit(@PathParam("oldKegID") int oldKegID, List<ScanTblKeg> entities) {
        final InventoryModifiers im = new InventoryModifiers();
        final ScanTblKeg oldKeg = super.find(oldKegID);
        //Find old fgi value and remove from inventory.
        FinishedGoodsInventory oldFGI = oldKeg.getKegFGI();
        if(oldFGI == null){
            oldFGI = getFGIViaPkgAndBeer(oldKeg.getKegPackageID().getPackageTypeID()
                    , oldKeg.getKegBeer().getbId());
        }
        im.doFGIRemovalWithoutAllocation(em, oldFGI.getFgiid(), 1);
        
        //Add new fgis into inventory.
        float newVolume = 0;
        if(entities != null){
            for(ScanTblKeg entity : entities){
                final FinishedGoodsInventory fgi = getFGIViaPkgAndBeer(
                        entity.getKegPackageID().getPackageTypeID()
                        , oldKeg.getKegBeer().getbId());
                entity.setKegBatch(oldKeg.getKegBatch());
                entity.setKegBeer(oldKeg.getKegBeer());
                entity.setKegFGI(fgi);
                super.edit(entity);
                im.doFGIAddition(em, fgi, 1);
                newVolume += entity.getKegPackageID().getPackageTypeVol();
            }
        }
        
        //Check volumes and determine if we need to enter a loss.
        final float volumeLeft = oldKeg.getKegPackageID().getPackageTypeVol() - newVolume;
        if(volumeLeft > 0){
            final java.util.Date MoveDate = new java.util.Date();
            LossLog loss = new LossLog();
            loss.setLAngelShare(0);
            loss.setLBeerID(0);
            loss.setLBtl(0);
            loss.setLCellar(0);
            loss.setLKeg(volumeLeft);
            loss.setLDate(MoveDate);
            loss.setLNotes("Loss due to keg transfer");
            em.persist(loss);
        }
        
        //Reset old keg customer info.
        oldKeg.setKegCust(null);
        em.merge(oldKeg);
    }
    
    @POST
    @Path("processKegLossesAndroid/{lossNotes}")
    @Consumes({"application/xml", "application/json"})
    public void editScanKegLossAndroid(@PathParam("lossNotes") String lossNotes, KegList entity) {
        if(entity.getScanTblKeg() != null){
            final InventoryModifiers im = new InventoryModifiers();
            float volume = 0;
            for(ScanTblKeg keg : entity.getScanTblKeg()){
                final FinishedGoodsInventory fgi = getFGIViaPkgAndBeer(
                        keg.getKegPackageID().getPackageTypeID()
                        , keg.getKegBeer().getbId());
                im.doFGIRemovalWithoutAllocation(em, fgi.getFgiid(), 1);
                volume += keg.getKegPackageID().getPackageTypeVol();
                keg.makeKegBeerNull();
                keg.makeKegCustNull();
                keg.makeKegFGINull();
                keg.setDateSold(null);
                keg.setKegBatch(0);
                super.edit(keg);
            }
            
            final java.util.Date MoveDate = new java.util.Date();
            LossLog loss = new LossLog();
            loss.setLAngelShare(0);
            loss.setLBeerID(0);
            loss.setLBtl(0);
            loss.setLCellar(0);
            loss.setLKeg(volume);
            loss.setLDate(MoveDate);
            loss.setLNotes(lossNotes);
            em.persist(loss);
        }
    }
    
    @POST
    @Path("processKegLosses/{lossNotes}")
    @Consumes({"application/xml", "application/json"})
    public void editScanKegLoss(@PathParam("lossNotes") String lossNotes, List<ScanTblKeg> entities) {
        if(entities != null){
            final InventoryModifiers im = new InventoryModifiers();
            float volume = 0;
            for(ScanTblKeg entity : entities){
                final FinishedGoodsInventory fgi = getFGIViaPkgAndBeer(
                        entity.getKegPackageID().getPackageTypeID()
                        , entity.getKegBeer().getbId());
                im.doFGIRemovalWithoutAllocation(em, fgi.getFgiid(), 1);
                volume += entity.getKegPackageID().getPackageTypeVol();
                entity.makeKegBeerNull();
                entity.makeKegCustNull();
                entity.makeKegFGINull();
                entity.setDateSold(null);
                entity.setKegBatch(0);
                super.edit(entity);
            }
            
            final java.util.Date MoveDate = new java.util.Date();
            LossLog loss = new LossLog();
            loss.setLAngelShare(0);
            loss.setLBeerID(0);
            loss.setLBtl(0);
            loss.setLCellar(0);
            loss.setLKeg(volume);
            loss.setLDate(MoveDate);
            loss.setLNotes(lossNotes);
            em.persist(loss);
        }
    }
    
    private FinishedGoodsInventory getFGIViaPkgAndBeer(final int packageID, final int beerID){
        TypedQuery<FinishedGoodsInventory> query = em.createQuery(
            "SELECT f FROM FinishedGoodsInventory f WHERE f.fGIPackageID.packageTypeID = ?1 AND f.bBeerID.bId = ?2"
                , FinishedGoodsInventory.class);
        query.setParameter(1, packageID);
        query.setParameter(2, beerID);
        FinishedGoodsInventory fgi = query.getSingleResult();
        return fgi;
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") Integer id) {
        super.remove(super.find(id));
    }

    @GET
    @Path("{id}")
    @Produces({"application/xml", "application/json"})
    public ScanTblKeg find(@PathParam("id") Integer id) {
        return super.find(id);
    }

    @GET
    @Override
    @Produces({"application/xml", "application/json"})
    public List<ScanTblKeg> findAll() {
        return super.findAll();
    }

    @GET
    @Path("{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<ScanTblKeg> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        return super.findRange(new int[]{from, to});
    }

    @GET
    @Path("count")
    @Produces("text/plain")
    public String countREST() {
        return String.valueOf(super.count());
    }

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    @GET
    @Path("namedQueryCount/{str}/{id}")
    @Produces("text/plain")
    public String namedQueryCount(@PathParam("str") String str
            , @PathParam("id") Integer id) {
        return String.valueOf(super.namedQueryCount(str, id, "kegID"));
    }
    
    @GET
    @Path("runNamedQueryWithID/{str}/{id}")
    @Override
    @Produces({"application/xml", "application/json"})
    public List<ScanTblKeg> runNamedQueryWithID(@PathParam("str") String str
            , @PathParam("id") int id){
        return super.runNamedQueryWithID(str, id);
    }
    
    @GET
    @Path("runQuery/{str}")
    @Override
    @Produces({"application/xml", "application/json"})
    public List<ScanTblKeg> runQuery(@PathParam("str") String str){
        return super.runQuery(str);
    }
    
}
